/*
 * Copyright (C) 2009 Rafael Fernandes
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.phonebooksharing.android.activities.privacy;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts.ContactMethods;
import android.provider.Contacts.GroupMembership;
import android.provider.Contacts.Groups;
import android.provider.Contacts.People;
import android.provider.Contacts.Phones;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.phonebooksharing.android.R;
import com.phonebooksharing.android.activities.setupwizard.SetupWizard4;
import com.phonebooksharing.android.util.CloseableUtil;
import com.phonebooksharing.android.util.Global;
import com.phonebooksharing.android.util.NetworkHandlerTask;
import com.phonebooksharing.dto.GenericTransferDTO;
import com.phonebooksharing.dto.ReturnItem;
import com.phonebooksharing.dto.GenericTransferDTO.GenericTransferItem;
import com.phonebooksharing.dto.friend.GroupItem;

@SuppressWarnings({"unchecked"})
public class PrivacyGroupSetupListActivity extends ListActivity {
	
	private GroupAdapter adapter;
	
	public static final String IS_INITIAL_SETUP = "i";
	
	private boolean isInitialSetup = false;
	
	@Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.group_selection);
        
        isInitialSetup = getIntent().getBooleanExtra(IS_INITIAL_SETUP, false);
        if(isInitialSetup) {
            addActionBar();
        } else {
            ((TextView)findViewById(android.R.id.text1)).setText("Group Setup");
            ((TextView)findViewById(android.R.id.text2)).setText("Now it is time to setup the visibility/privacy " +
                    "of your groups.\nThis can be changed afterwards as well.");
        }
        
        View empty = LayoutInflater.from(this).inflate(R.layout.empty_progress, null);
        ((TextView)empty.findViewById(android.R.id.text1)).setText("Please wait while we load your groups.");
        getListView().setEmptyView(empty);
        
        new LoadGroupsTask(this).execute();
	}

    protected void addActionBar() {
        ((TextView)findViewById(android.R.id.text1)).setText("Phonebook Sharing Accout Setup (2/4)");
        ((TextView)findViewById(android.R.id.text2)).setText("Now it is time to setup the visibility/privacy " +
                "of your groups.\nThis can be changed afterwards as well.");

        findViewById(R.id.actionStub).setVisibility(View.VISIBLE);
        
        ((Button)findViewById(android.R.id.button1)).setVisibility(View.INVISIBLE);
        
        Button next = (Button)findViewById(android.R.id.button2);
        next.setText("Next");
        next.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.next, 0);
        next.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if(check()) { 
					new SendContentTask(PrivacyGroupSetupListActivity.this).execute();
				} else {
					new AlertDialog.Builder(PrivacyGroupSetupListActivity.this)
				            .setIcon(android.R.drawable.ic_dialog_alert)
				            .setTitle("Invalid Group Privacy")
				            .setMessage("You cannot have only Invisible Groups!\n\nPlease select at least one to proceed.")
				            .setPositiveButton("OK", null)
		            .create().show();
				}
			}
		});
    }
	
	class SendContentTask extends NetworkHandlerTask<Void, Void, Void> {
		private ProgressDialog progress;
		private Context cx;
		
		SendContentTask(Context c) {
			this.cx = c;
		}
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			progress = new ProgressDialog(PrivacyGroupSetupListActivity.this);
			progress.setIcon(android.R.drawable.ic_dialog_info);
			progress.setTitle("Working...");
			progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

			progress.setMessage("Creating Profile/Sending contents...");
			progress.setMax(7);
			progress.show();
		}

		@Override
		protected Void doInBackground(Void... arg0) {
			Cursor people = null, contactMethods = null, 
				   phones = null, groups = null, 
				   groupMember = null;
			try {
				publishProgress();//just to start the progress with something
				final ContentResolver cr = cx.getContentResolver();
				final String authItem = Global.authItem;

				people = cr.query(People.CONTENT_URI, new String[]{
						People._ID, People.NAME}, null, null, null);
				if(people != null && people.moveToFirst()) {
					final int id = people.getColumnIndex(People._ID), 
							  name = people.getColumnIndex(People.NAME);
					final GenericTransferDTO gt = new GenericTransferDTO();
					GenericTransferItem g;
					gt.authItem = authItem;
					do {
						g = gt.new GenericTransferItem();
						g.id = people.getInt(id);
                        g.contactID = people.getInt(id);
						g.field1 = people.getString(name);
						gt.items.add(g);
					} while (people.moveToNext());
					
					if(gt.items.size() > 0) {
						final String url = String.format(Global.PROFILE_SERVLET_URL, "a" /*ac*/, "c" /*q*/);//create contacts/people
						ReturnItem ri = (ReturnItem)doNetworkPost(url, gt); //should be ok
						if(!ri.isOK()) {
							
						}
					}
				}
				publishProgress();
				
				phones = cr.query(Phones.CONTENT_URI, new String[]{
						Phones._ID, Phones.PERSON_ID, Phones.TYPE, Phones.NUMBER, Phones.NUMBER_KEY, Phones.ISPRIMARY
				}, null, null, null);
				if(phones != null && phones.moveToFirst()) {
					final int id        = phones.getColumnIndex(Phones._ID), 
					  		  person    = phones.getColumnIndex(Phones.PERSON_ID),
					  		  type 	    = phones.getColumnIndex(Phones.TYPE),
					  		  number    = phones.getColumnIndex(Phones.NUMBER), 
					  		  numberKey = phones.getColumnIndex(Phones.NUMBER_KEY),
					  		  isPrimary = phones.getColumnIndex(Phones.ISPRIMARY);
					final GenericTransferDTO gt = new GenericTransferDTO();
					GenericTransferItem g;
					gt.authItem = Global.authItem;
					do {
					    g = gt.new GenericTransferItem();
                        g.id        = phones.getInt(id);
                        g.contactID = phones.getInt(person);
                        g.field1    = phones.getString(type);
                        g.field2    = phones.getString(number);
                        g.field3    = phones.getString(numberKey);
                        g.field4    = phones.getString(isPrimary);
                        gt.items.add(g);
					} while (phones.moveToNext());
					
					if(gt.items.size() > 0) {
                        final String url = String.format(Global.PROFILE_SERVLET_URL, "a" /*ac*/, "p" /*q*/);//action validate
                        ReturnItem ri = (ReturnItem)doNetworkPost(url, gt); //should be ok
                        if(!ri.isOK()) {
                            
                        }
                    }
					gt.items = null;
				}
				publishProgress();

				contactMethods = cr.query(ContactMethods.CONTENT_URI, new String[]{
						ContactMethods._ID, ContactMethods.PERSON_ID, ContactMethods.LABEL, 
						ContactMethods.KIND, ContactMethods.TYPE, ContactMethods.DATA, 
						ContactMethods.AUX_DATA, ContactMethods.ISPRIMARY
				}, null, null, null);
				if(contactMethods != null && contactMethods.moveToFirst()) {
				    final int   id          = contactMethods.getColumnIndex(ContactMethods._ID), 
                                personID    = contactMethods.getColumnIndex(ContactMethods.PERSON_ID),
                                label       = contactMethods.getColumnIndex(ContactMethods.LABEL),
                                kind        = contactMethods.getColumnIndex(ContactMethods.KIND),
                                type        = contactMethods.getColumnIndex(ContactMethods.TYPE), 
                                data        = contactMethods.getColumnIndex(ContactMethods.DATA),
                                aux         = contactMethods.getColumnIndex(ContactMethods.AUX_DATA),
                                isPrimary   = contactMethods.getColumnIndex(ContactMethods.ISPRIMARY);
				    
				    final GenericTransferDTO gt = new GenericTransferDTO();
                    GenericTransferItem g;
                    gt.authItem = Global.authItem;
                    do {
                        g = gt.new GenericTransferItem();
                        g.id        = contactMethods.getInt(id);
                        g.contactID = contactMethods.getInt(personID);
                        g.field1    = contactMethods.getString(label);
                        g.field2    = contactMethods.getString(kind);
                        g.field3    = contactMethods.getString(type);
                        g.field4    = contactMethods.getString(data);
                        g.field5    = contactMethods.getString(aux);
                        g.field6    = contactMethods.getString(isPrimary);
                        gt.items.add(g);
                    } while (contactMethods.moveToNext());
                    
                    if(gt.items.size() > 0) {
                        final String url = String.format(Global.PROFILE_SERVLET_URL, "a" /*ac*/, "cm" /*q*/);//action validate
                        ReturnItem ri = (ReturnItem)doNetworkPost(url, gt); //should be ok
                        if(!ri.isOK()) {
                            
                        }
                    }
                    gt.items = null;
				}
				publishProgress();

                final ArrayList<GroupItem> list = adapter.groups;
                if(list.size() > 0) {
                    final GenericTransferDTO gt = new GenericTransferDTO();
                    gt.authItem = Global.authItem;
                    GenericTransferItem g;
                    StringBuffer sb;
                    int l;
                    for(GroupItem item : list) {
                        g  = gt.new GenericTransferItem();
                        sb = new StringBuffer();
                        
                        g.id = item.id;
                        g.field1 = item.name;
                        g.field2 = "" + item.contactPrivacy;
                        g.field4 = "" + item.imagePrivacy;
                        g.field5 = "" + item.videoPrivacy;
                        g.field6 = "" + item.postCardPrivacy;
                        g.field7 = "" + item.wishListPrivacy;
                        
                        ArrayList<Integer> grant = item.grantGroups;
                        for(int i : grant) {
                            sb.append(i);
                            sb.append(",");
                        }
                        if((l = sb.length()) > 0) {
                            g.field3 = sb.substring(0, l -1);//remove last and add
                        }
                        gt.items.add(g);
                    }
                    
                    final String url = String.format(Global.PROFILE_SERVLET_URL, "a" /*ac*/, "g" /*q*/);//action validate
                    ReturnItem ri = (ReturnItem)doNetworkPost(url, gt); //should be ok
                    if(!ri.isOK()) {
                        
                    }
                    gt.items  = null;
                }
				
//				groups = cr.query(Groups.CONTENT_URI, new String[]{Groups._ID, Groups.NAME}, null, null, null);
//				if(groups != null && groups.moveToFirst()) {
//                    final int   id     = groups.getColumnIndex(Groups._ID), 
//                                name   = groups.getColumnIndex(Groups.NAME);
//        
//                    final GenericTransferDTO gt = new GenericTransferDTO();
//                    GenericTransferItem g;
//                    gt.authItem = Global.authItem;
//                    do {
//                        g = gt.new GenericTransferItem();
//                        g.id     = groups.getString(id);
//                        g.field1 = groups.getString(name);
//                        gt.items.add(g);
//                    } while (groups.moveToNext());
//                    
//                    if(gt.items.size() > 0) {
//                        final String url = String.format(Global.BASE_URL + "/ProfileServlet?ac=a&q=g");//action validate
//                        ReturnItem ri = (ReturnItem)doNetworkPost(url, gt); //should be ok
//                        if(!ri.isOK()) {
//                            
//                        }
//                    }
//                    gt.items = null;
//				} 
				publishProgress();
				
				groupMember = cr.query(GroupMembership.CONTENT_URI, new String[]{
						GroupMembership._ID, GroupMembership.GROUP_ID, GroupMembership.PERSON_ID
				}, null, null, null);
				if(groupMember != null && groupMember.moveToFirst()) {
                    final int   gID   = groupMember.getColumnIndex(GroupMembership.GROUP_ID),
                                pID   = groupMember.getColumnIndex(GroupMembership.PERSON_ID);

                    final GenericTransferDTO gt = new GenericTransferDTO();
                    GenericTransferItem g;
                    gt.authItem = Global.authItem;
                    do {
                        g = gt.new GenericTransferItem();
                        g.id        = groupMember.getInt(gID);
                        g.contactID = groupMember.getInt(pID);
                        gt.items.add(g);
                    } while (groupMember.moveToNext());
                    
                    if(gt.items.size() > 0) {
                        final String url = String.format(Global.PROFILE_SERVLET_URL, "a" /*ac*/, "gm" /*q*/);//action validate
                        ReturnItem ri = (ReturnItem)doNetworkPost(url, gt); //should be ok
                        if(!ri.isOK()) {
                            
                        }
                    }
                    gt.items = null;
				}
				publishProgress();
				
				final GenericTransferDTO gt = new GenericTransferDTO();
                gt.authItem = Global.authItem;
                
				final String url = String.format(Global.PROFILE_SERVLET_URL, "d" /*ac*/, "" /*q*/);//action done sending contents
				doNetworkPost(url, gt);
				
				publishProgress();
                
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				CloseableUtil.safeClose(people);
				CloseableUtil.safeClose(contactMethods);
				CloseableUtil.safeClose(phones);
				CloseableUtil.safeClose(groups);
				CloseableUtil.safeClose(groupMember);
				
				people = null; contactMethods = null; phones = null;
                groups = null; groupMember = null;
			}
			
			return null;
		}
		
		@Override
		protected void onProgressUpdate(Void... values) {
			super.onProgressUpdate(values);
			progress.incrementProgressBy(1);
		}
		
		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			progress.dismiss();
			startActivity(new Intent(PrivacyGroupSetupListActivity.this, SetupWizard4.class));
			finish();
		}
	}
	
	private boolean check() {
		final ArrayList<GroupItem> al = adapter.groups;
		for(GroupItem gi : al) {
		    if(!gi.isSetupDone()) {
		        return false;
		    }
		}
		return true;
	}

//   private boolean check() {
//        final ArrayList<GroupItem> al = adapter.groups;
//        int pr = 0;
//        for(GroupItem gi : al) {
//            if(gi.contactPrivacy == 3) {
//                pr++;
//            }
//        }
//        
//        //3 is the position of invisible
//        return (pr != al.size());//if the rest is 0, means all are invisible, throw error
//    }

	static class GroupAdapter extends BaseAdapter {
        private ArrayList<GroupItem> groups;
        private LayoutInflater inflater;

        public GroupAdapter(Context c, ArrayList<GroupItem> groups) {
            this.groups = groups;
            this.inflater = LayoutInflater.from(c);
        }

        public int getCount() {
            return groups.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }
        
        public View getView(int position, View cv, ViewGroup parent) {
        	ViewHolder holder;
            if(cv == null) {
                cv = inflater.inflate(R.layout.list_item_3lines, parent, false);
                holder = new ViewHolder();
//                holder.icon = (ImageView)cv.findViewById(R.id.icon);
                holder.text1 = (TextView)cv.findViewById(android.R.id.text1);
                holder.text3 = (TextView)cv.findViewById(R.id.text3);
                holder.text4 = (TextView)cv.findViewById(R.id.text4);
                holder.text5 = (TextView)cv.findViewById(R.id.text5);

                cv.setTag(holder);
            } else {
                holder = (ViewHolder)cv.getTag();
            }
            
            final GroupItem gi = groups.get(position);
            holder.text1.setText("Group: " + gi.name);
            holder.text3.setText("Click on this group to change its privacy");
            holder.text4.setText("Privacy: ");
            
            final String setup = (gi.isSetupDone() ? "Setup Done" : "Setup not Done");
            holder.text5.setText(setup);
            
            return cv;
        }
        
        static class ViewHolder {
//        	ImageView icon;
        	TextView text1, text3, text4, text5;
        }
    }
	
	@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		final GroupItem gi = adapter.groups.get(position);
		Intent i = new Intent(this, PrivacyGroupSetupActivity.class);
		i.putExtra(PrivacyGroupSetupActivity.ID,       gi.id);
		i.putExtra(PrivacyGroupSetupActivity.POSITION, position);
		i.putExtra(PrivacyGroupSetupActivity.TITLE,    gi.name);
		
		startActivityForResult(i, 0);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		if(resultCode == RESULT_OK) {
			final int contactPrivacyChosen = data.getIntExtra(PrivacyGroupSetupActivity.CONTACT_PRIVACY_CHOSEN, -1);
			GroupItem gi = adapter.groups.get(data.getIntExtra(PrivacyGroupSetupActivity.POSITION, -1));
			gi.contactPrivacy  = contactPrivacyChosen;
			gi.imagePrivacy    = data.getIntExtra(PrivacyGroupSetupActivity.IMAGE_PRIVACY_CHOSEN, -1);
            gi.videoPrivacy    = data.getIntExtra(PrivacyGroupSetupActivity.VIDEO_PRIVACY_CHOSEN, -1);
            gi.postCardPrivacy = data.getIntExtra(PrivacyGroupSetupActivity.POSTCARD_PRIVACY_CHOSEN, -1);
            gi.wishListPrivacy = data.getIntExtra(PrivacyGroupSetupActivity.WISH_LIST_PRIVACY_CHOSEN, -1);

			if((PrivacyGroupSetupActivity.PRIVACY_OPTIONS.length - 1) == contactPrivacyChosen) {
				final ArrayList<Integer> grantGroups = data.getIntegerArrayListExtra(PrivacyGroupSetupActivity.GRANT_GROUPS);
				gi.grantGroups = grantGroups;
			}
			adapter.notifyDataSetChanged();
		}
	}
	
	class LoadGroupsTask extends NetworkHandlerTask<Void, ArrayList<GroupItem>, Void> {
		private Context c;
		LoadGroupsTask(Context c) {
			this.c = c;
		}
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected Void doInBackground(Void... params) {

			final ContentResolver cr = c.getContentResolver();
			final ArrayList<GroupItem> list = new ArrayList<GroupItem>();
			Cursor c = null;
			try {
				c = cr.query(Groups.CONTENT_URI, null, Groups.NAME + " not in (?)", 
						new String[]{"System Group: My Contacts"}, Groups.NAME);
				int id, name;
				if (c != null && c.moveToFirst()) {
					id    = c.getColumnIndex(Groups._ID);
					name  = c.getColumnIndex(Groups.NAME);
					do {
						list.add(new GroupItem(c.getInt(id), c.getString(name)));
					} while (c.moveToNext());
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				CloseableUtil.safeClose(c);
				c = null;
			}

			publishProgress(list);
			return null;
		}
		
		@Override
		protected void onProgressUpdate(ArrayList<GroupItem>... values) {
			super.onProgressUpdate(values);
			final ArrayList<GroupItem> list = values[0];
			adapter = new GroupAdapter(c, list);
			final ListView elv = getListView();
			elv.setAdapter(adapter);
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
		}
	}

    @Override
    public void finish() {
        super.finish();
        if(isInitialSetup) return;
        
        if(!check()) {
            Toast.makeText(this, "In order to update your privacy, you'd have to revisit all the groups!", Toast.LENGTH_LONG).show();
        } else {
            new UpdateConfigTask().execute();
        }
    }
    
    class UpdateConfigTask extends NetworkHandlerTask<Void, Void, Void> {
//        private ProgressDialog d;
        
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

//            d = new ProgressDialog(PrivacyGroupSetupListActivity.this);
//            d.setTitle("Updating Privacy");
//            d.setMessage("Please wait while process your request...");
//            d.setIndeterminate(true);
//            d.setCancelable(true);
//            d.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            try {
                GenericTransferDTO g = new GenericTransferDTO();
                g.authItem = Global.authItem;
                g.items2 = adapter.groups;
                
                final String url = String.format(Global.PROFILE_SERVLET_URL, "upr" /*ac*/, "" /*q*/);
                ReturnItem ri = (ReturnItem)doNetworkPost(url, g);
                if(ri.isOK()) {
                    
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        
        @Override
        protected void onPostExecute(Void i) {
            super.onPostExecute(i);

//            d.dismiss();
            Toast.makeText(PrivacyGroupSetupListActivity.this, "Your privacy has been successfuly updated!", Toast.LENGTH_LONG).show();
        }
    }
}
